import 'dart:math';
import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_custompaint_first/Widget/Utils/Utils.dart';
/**
 * Create by laoge
 * on 2021/4/26 0026
 */

class BarChartPainter extends CustomPainter {
  Paint scalePaint = new Paint()
    ..color = Colors.grey
    ..strokeWidth = 1
    ..style = PaintingStyle.stroke;
  Padding padding =
      new Padding(padding: EdgeInsets.symmetric(vertical: 20, horizontal: 40));

  Paint barPaint = new Paint()
    ..color = Colors.lightBlueAccent
    ..strokeWidth = 1
    ..style = PaintingStyle.fill;

  // X轴刻度间一个单位长度
  final double interval;

  // 刻度的高度
  double intervalHeight = 5;

  // 轴刻度文字大小
  double intervalFontSize = 14;

  // Y轴一个单位刻度长度
  double yInterval = 30;

  // 单位柱状条的宽度
  final double barWidth;

  BuildContext context;
  final Map<dynamic, int> data;

  BarChartPainter(this.context, this.data,
      {this.interval = 40, this.barWidth = 20}) {
    assert(barWidth < interval, "barWidth must small than interval");
    biggest = findBiggest(data);
  }

  ui.ParagraphBuilder paragraphBuilder;
  double w, h;
  int random = 0, biggest = 0;
  ui.Paragraph paragraph;

  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    // 画X轴
    canvas.drawLine(
        Offset(padding.padding.horizontal / 2,
            size.height - padding.padding.vertical / 2),
        Offset(size.width - padding.padding.horizontal / 2,
            size.height - padding.padding.vertical / 2),
        scalePaint);
    // X轴的箭头
    canvas.drawLine(
        Offset(size.width - padding.padding.horizontal / 2 - intervalHeight,
            size.height - padding.padding.vertical / 2 - intervalHeight),
        Offset(size.width - padding.padding.horizontal / 2,
            size.height - padding.padding.vertical / 2),
        scalePaint);
    canvas.drawLine(
        Offset(size.width - padding.padding.horizontal / 2 - intervalHeight,
            size.height - padding.padding.vertical / 2 + intervalHeight),
        Offset(size.width - padding.padding.horizontal / 2,
            size.height - padding.padding.vertical / 2),
        scalePaint);
    // X轴刻度
    for (int i = 0; i <= data.length; i++) {
      if (i != 0) {
        dynamic key = data.keys.toList()[i-1];
        random = data[key];
        // 绘制刻度
        canvas.drawLine(
            Offset(padding.padding.horizontal / 2 + (i * interval),
                size.height - padding.padding.vertical / 2),
            Offset(padding.padding.horizontal / 2 + (i * interval),
                size.height - padding.padding.vertical / 2 + intervalHeight),
            scalePaint);
        w = Utils.calculateTextHeightAndWidth(
                context, random.toString(), intervalFontSize)
            .width;
        h = Utils.calculateTextHeightAndWidth(
                context, random.toString(), intervalFontSize)
            .height;
        // 绘制柱状条值
        buildParagraph(random.toString());
        canvas.drawParagraph(
            paragraph,
            Offset(
                padding.padding.horizontal / 2 + (i * interval) - w / 2,
                size.height -
                    padding.padding.vertical / 2 -
                    ((size.height - padding.padding.vertical ) /
                        biggest *
                        random) -
                    h));
        // 绘制柱状条
        canvas.drawRect(
            Rect.fromPoints(
                Offset(
                    padding.padding.horizontal / 2 +
                        (i * interval) -
                        barWidth / 2,
                    size.height - padding.padding.vertical / 2),
                Offset(
                    padding.padding.horizontal / 2 +
                        (i * interval) +
                        barWidth / 2,
                    size.height -
                        padding.padding.vertical / 2 -
                        ((size.height - padding.padding.vertical) /
                            biggest *
                            random))),
            barPaint);
        w = Utils.calculateTextHeightAndWidth(
            context, (key).toString(), intervalFontSize)
            .width;
        // 绘制刻度文本
        buildParagraph(key.toString());
        canvas.drawParagraph(
            paragraph,
            Offset(padding.padding.horizontal / 2 + (i * interval) - w / 2,
                size.height - padding.padding.vertical / 2 + intervalHeight));
      }

    }

    // 画Y轴
    canvas.drawLine(
        Offset(padding.padding.horizontal / 2,
            size.height - padding.padding.vertical / 2),
        Offset(padding.padding.horizontal / 2, padding.padding.vertical / 2),
        scalePaint);
    // Y轴的箭头
    canvas.drawLine(
        Offset(padding.padding.horizontal / 2 - intervalHeight,
            padding.padding.vertical / 2 + intervalHeight),
        Offset(padding.padding.horizontal / 2, padding.padding.vertical / 2),
        scalePaint);
    canvas.drawLine(
        Offset(padding.padding.horizontal / 2 + intervalHeight,
            padding.padding.vertical / 2 + intervalHeight),
        Offset(padding.padding.horizontal / 2, padding.padding.vertical / 2),
        scalePaint);
    double tempInterval = biggest ~/ 10 * 10 / 3;
    for (int i = 1; i <= 3; i++) {
      // 绘制刻度
      canvas.drawLine(
          Offset(
              padding.padding.horizontal / 2,
              size.height -
                  padding.padding.vertical / 2 -
                  (size.height - padding.padding.vertical) / 3 * i +
                  10),
          Offset(
              padding.padding.horizontal / 2 + intervalHeight,
              size.height -
                  padding.padding.vertical / 2 -
                  (size.height - padding.padding.vertical) / 3 * i +
                  10),
          scalePaint);
      // 绘制刻度文本
      w = Utils.calculateTextHeightAndWidth(
              context, (i * tempInterval).toStringAsFixed(0), intervalFontSize)
          .width;
      h = Utils.calculateTextHeightAndWidth(
              context, (i * tempInterval).toStringAsFixed(0), intervalFontSize)
          .height;
      buildParagraph((i * tempInterval).toStringAsFixed(0));
      canvas.drawParagraph(
          paragraph,
          Offset(
              padding.padding.horizontal / 2 - w - 5,
              size.height -
                  padding.padding.vertical / 2 -
                  (size.height - padding.padding.vertical) / 3 * i +
                  10 -
                  h / 2));
    }
  }

  void buildParagraph(String i) {
    paragraphBuilder = ui.ParagraphBuilder(
      ui.ParagraphStyle(
          textDirection: ui.TextDirection.ltr,
          fontSize: intervalFontSize,
          textAlign: TextAlign.center),
    )
      ..pushStyle(ui.TextStyle(color: Colors.grey))
      ..addText(i);

    paragraph = paragraphBuilder.build()
      ..layout(ui.ParagraphConstraints(width: w));
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }

  int findBiggest(Map<dynamic, int> data) {
    int biggest ;
    for (var i = 0; i < data.keys.length; ++i) {
      dynamic key = data.keys.toList()[i];
      int element = data[key];
      if(i==0){
        biggest = element;
      }else{
        biggest = biggest > element ? biggest : element;
      }
    }
    return biggest;
  }
}
